package com.yanqu.road.server.manger.activity.guagifts;

import com.yanqu.road.dao.impl.player.UserGuaDaoImpl;
import com.yanqu.road.dao.impl.player.UserGuaNobleRelationDaoImpl;
import com.yanqu.road.dao.impl.player.UserGuaRelationDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.guagifts.UserGuaData;
import com.yanqu.road.entity.activity.guagifts.UserGuaNobleRelationData;
import com.yanqu.road.entity.activity.guagifts.UserGuaRelationData;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.activity.GuaGiftsConfig.GuaGiftsConfig;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.thread.ThreadTaskManger;
import com.yanqu.road.pb.activity.GuaGiftsProto;
import com.yanqu.road.pb.activity.QixiProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.game.service.GameService;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.guagifts.GuaGiftsModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.guagifts.service.*;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.relatives.RelativesMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.sync.message.SyncResponse;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

public class GuaGiftsMgr extends TempMgr {
    private static GuaGiftsConfig config;

    private static ThreadTaskManger threadTaskManger;

    private static List<Long> allServerList = new ArrayList<>();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        if (null == threadTaskManger) {
            threadTaskManger = new ThreadTaskManger(1, "GuaMgr");
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }

    @Override
    public boolean save() {
        return true;
    }

    public static void reloadActivity() {
        getLogger().info("guagifts reloadActivity start");
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.GuaGiftsActivity.getValue());
        if (openActivityInfoList.isEmpty()) {
            getLogger().info("no guagifts Activity in show time");
            config = null;
            allServerList = new ArrayList<>();
        } else {
            ActivityInfo tempActivityInfo = openActivityInfoList.get(0);
            List<Integer> activityIdList = new ArrayList<>();
            int activityId = tempActivityInfo.getActivityId();
            activityIdList.add(activityId);
            Map<String, ActivityConfig> activityConfigMap = ActivityMgr.getActivityConfigMap(activityId);
            GuaGiftsConfig configTemp = new GuaGiftsConfig(tempActivityInfo, activityConfigMap);
            String nowTimeStr = DateHelper.getCurrentDateTimeString();
            Set<Long> serverIdSet = ActivityBussiness.getAllOpenServerListByActivityType(tempActivityInfo.getType(), nowTimeStr);
            config = configTemp;
            allServerList = new ArrayList<>(serverIdSet);
        }

        getLogger().info("guagifts reloadActivity end");

        for (GamePlayer player : GamePlayerMgr.getAllOnlinePlayer()) {
            player.getModule(GuaGiftsModule.class).initUserData();
            player.getModule(GuaGiftsModule.class).syncUserData();
        }
    }

    public static GuaGiftsConfig getConfig() {
        return config;
    }

    public static void initService(GameService syncMessageService) {
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_SEND_GIFTS, new GuaSendGiftServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_SEARCH_USER, new GuaSearchUserServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER_FROM_GAME, new GuaGetMostGiftTargetUserBackServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_SEND_GIFTS_ASYNC_BACK, new GuaSendGiftAsyncBackServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER, new GuaGetMostGiftTargetUserServiceCmd());
        syncMessageService.addGameServiceCommand(GameProtocol.S_GUAGIFTS_GIFT_BROADCAST_FROM_OTHER, new GuaNewBroadcastFromOtherServiceCmd());
    }

    public static GuaGiftsProto.CrossGuaGiftsSendGiftRespMsg.Builder receiveGift(long sendServerId, long sendUserId, long targetId, int giftId, int giftCount, String content) {
        GuaGiftsProto.CrossGuaGiftsSendGiftRespMsg.Builder backMsg = GuaGiftsProto.CrossGuaGiftsSendGiftRespMsg.newBuilder();
        backMsg.setRet(0);
        backMsg.setGiftId(giftId);
        backMsg.setGiftCount(giftCount);
        backMsg.setTargetUserId(targetId);

        if (getConfig() == null) {
            //没活动的服,直接返回结果
            backMsg.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
//            UserInfo userInfo = UserMgr.getUserInfo(targetId);
//            if (userInfo == null) {
//                backMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
//            } else {
//                backMsg.setRet(0);
//                backMsg.setTargetUserId(targetId);
//                backMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId())));
//                backMsg.setContent(content);
//                backMsg.setSendUserId(sendUserId);
//            }
        } else {
            try {
                GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(targetId);
                if (onlinePlayer != null) {
                    UserGuaData userData = onlinePlayer.getModule(GuaGiftsModule.class).getUserData();
                    if (userData != null) {
                        GoodsInfo giftInfo = GoodsMgr.getGoodsById(giftId);
                        if (giftInfo != null) {
                            int receiveLimit = giftInfo.getParamList().get(3).intValue();
                            if (receiveLimit != -1) {
                                //有接收数量限制
                                int dayCount = userData.getDayCountMap().getOrDefault(giftId, 0);

                                if (dayCount >= receiveLimit) {
                                    backMsg.setRemainCanReceive(0);
                                    return backMsg.setRet(GameErrorCode.E_GUAGIFTS_GIFT_RECEIVE_LIMIT);
                                }

                                if (dayCount + giftCount > receiveLimit) {
                                    backMsg.setRemainCanReceive(receiveLimit - dayCount);
                                    return backMsg.setRet(GameErrorCode.E_GUAGIFTS_GIFT_RECEIVE_LIMIT);
                                }
                            }
                        }
                    }
                }
            } catch (Exception e) {
                getLogger().error("receiveGift error", e);
                return null;
            }


            UserInfo userInfo = UserMgr.getUserInfo(targetId);
            if (userInfo != null) {
                threadTaskManger.addTask(0, new GuaGiftsReceiveGiftTask(sendServerId, sendUserId, targetId, giftId, giftCount, content));
                return null;
            } else {
                return backMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
            }
        }

        return backMsg;
    }

    public static GuaGiftsProto.GuaGiftsSearchUserRespMsg.Builder searchUser(long userAliasId, int giftType) {
        GuaGiftsProto.GuaGiftsSearchUserRespMsg.Builder respMsg = GuaGiftsProto.GuaGiftsSearchUserRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setGiftType(giftType);
        if (getConfig() == null || !ActivityMgr.activityInTime(getConfig().getActivityInfo())) {
            return respMsg.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
        }
        UserInfo userInfo = UserMgr.getUserInfoByAliasId(userAliasId);
        if (userInfo == null) {
            return respMsg.setRet(GameErrorCode.E_USER_NO_FOUND);
        }

        UserBaseInfo userBaseInfo = UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId());
        GuaGiftsProto.GuaGiftsRelationTemp.Builder relationTemp = GuaGiftsProto.GuaGiftsRelationTemp.newBuilder();
        relationTemp.setTargetUserId(userInfo.getUserId());
        relationTemp.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        relationTemp.setSendGiftCount(0);
        relationTemp.setGetGiftCount(0);
        relationTemp.setTotalGiftCount(0);

        if (GuaGiftsMgr.getConfig() != null){
            UserGuaData userGuaData = null;
            GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(userInfo.getUserId());
            if (onlinePlayer != null) {
                userGuaData = onlinePlayer.getModule(GuaGiftsModule.class).getUserData();
            }else{
                userGuaData = new UserGuaDaoImpl().getUserGuaData(GuaGiftsMgr.getConfig().getActivityId(), userInfo.getUserId());
            }
            if (userGuaData != null) {
                if (giftType == 1){
                    relationTemp.setTotalGiftCount(userGuaData.getNobleValue());
                }else if (giftType == 2){
                    relationTemp.setTotalGiftCount(userGuaData.getGuaValue());
                }
            }
        }
        respMsg.setUserRelation(relationTemp);

        return respMsg;
    }

    public static long getGiftMostUserIdByRelationMap(Map<Long, UserGuaRelationData> dataMap) {
        int maxCount = 0;
        long maxCountUserId = 0;
        long compareTime = 0;
        for (UserGuaRelationData relationData : dataMap.values()) {
            if (maxCountUserId == 0) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetCount() == maxCount && relationData.getGetTime() > compareTime) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetCount() > maxCount) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }
        }

        return maxCountUserId;
    }

    public static long getNobleGiftMostUserIdByRelationMap(Map<Long, UserGuaNobleRelationData> dataMap) {
        int maxCount = 0;
        long maxCountUserId = 0;
        long compareTime = 0;
        for (UserGuaNobleRelationData relationData : dataMap.values()) {
            if (maxCountUserId == 0) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetCount() == maxCount && relationData.getGetTime() > compareTime) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }

            if (relationData.getGetCount() > maxCount) {
                maxCount = relationData.getGetCount();
                maxCountUserId = relationData.getTargetUserId();
                compareTime = relationData.getGetTime();
            }
        }

        return maxCountUserId;
    }

    public static void getGiftTargetMostUserInfo(long fromServerId, long fromUserId, long targetUserId, int giftType) {

        long targetServerId = RelativesMgr.getUserServerId(targetUserId);
        CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(targetUserId);
        if (unionMember != null) {
            targetServerId = unionMember.getServerId();
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(targetUserId);
            if (userInfo != null) {
                targetServerId = userInfo.getOriginalServerId();
            }
        }

        if (targetServerId == GameServer.getInstance().getServerId()) {
            GamePlayer onlinePlayer = GamePlayerMgr.getOnlinePlayer(targetUserId);
            long giftMostUserId = 0;
            if (onlinePlayer != null) {
                giftMostUserId = onlinePlayer.getModule(GuaGiftsModule.class).getGiftMostUserId(giftType);
            } else {
                if (giftType == 1){
                    Map<Long, UserGuaNobleRelationData> userRelationDataMap = new UserGuaNobleRelationDaoImpl().getUserGuaNobleRelationData(getConfig().getActivityId(), targetUserId);
                    giftMostUserId = getNobleGiftMostUserIdByRelationMap(userRelationDataMap);
                }else{
                    Map<Long, UserGuaRelationData> userGuaRelationDataMap = new UserGuaRelationDaoImpl().getUserGuaRelationData(getConfig().getActivityId(), targetUserId);
                    giftMostUserId = getGiftMostUserIdByRelationMap(userGuaRelationDataMap);
                }
            }

            getUserInfoByMostGiftUserId(fromServerId, fromUserId, targetUserId, giftMostUserId, giftType);
        } else {//去其他服取
            GuaGiftsProto.GuaGiftsGetMostGiftTargetUserReqMsg.Builder reqMsg = GuaGiftsProto.GuaGiftsGetMostGiftTargetUserReqMsg.newBuilder();
            reqMsg.setActivityId(GuaGiftsMgr.getConfig().getActivityId());
            reqMsg.setTargetUserId(targetUserId);
            reqMsg.setGiftType(giftType);

            GuaGiftsProto.CrossGuaGiftsGetMostGiftTargetUserRespMsg.Builder resp = GuaGiftsProto.CrossGuaGiftsGetMostGiftTargetUserRespMsg.newBuilder();

            CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(targetServerId, GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER, fromUserId, reqMsg, resp);
            future.thenAccept((SyncResponse syncResponse) -> {
                if (syncResponse.getErrorCode() != 0) {
                    getLogger().error("getGiftTargetMostUserInfo error, errorCode:{}", syncResponse.getErrorCode());
                    return;
                }

                getUserInfoByMostGiftUserId(fromServerId, fromUserId, targetUserId, resp.getUserId(), giftType);
            });
        }
    }

    public static void getUserInfoByMostGiftUserId(long fromServerId, long fromUserId, long targetUserId, long mostGiftUserId, int giftType) {
        UserBaseInfo userBaseInfo = null;

        CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(mostGiftUserId);
        if (unionMember != null) {
            userBaseInfo = unionMember.getUserBaseInfo();
        } else {
            UserInfo userInfo = UserMgr.getUserInfo(mostGiftUserId);
            if (userInfo != null) {
                userBaseInfo = UserMgr.parseUserBaseInfo(userInfo, GameServer.getInstance().getServerId());
            }
        }

        if (userBaseInfo == null) {
            long targetServerId = RelativesMgr.getUserServerId(mostGiftUserId);

            QixiProto.QixiGetUserInfoReqMsg.Builder reqMsg = QixiProto.QixiGetUserInfoReqMsg.newBuilder();
            reqMsg.setActivityId(GuaGiftsMgr.getConfig().getActivityId());
            reqMsg.addTargetUserId(mostGiftUserId);
            reqMsg.setReqProtocolType(GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER);

            QixiProto.QixiGetUserInfoRespMsg.Builder resp = QixiProto.QixiGetUserInfoRespMsg.newBuilder();

            CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(targetServerId, GameProtocol.S_QIXI_GET_USER_INFO, fromUserId, reqMsg, resp);
            future.thenAccept((SyncResponse syncResponse) -> {
                GuaGiftsProto.GuaGiftsGetMostGiftTargetUserRespMsg.Builder resultMsg = GuaGiftsProto.GuaGiftsGetMostGiftTargetUserRespMsg.newBuilder();
                resultMsg.setRet(0);
                if (syncResponse.getErrorCode() != 0) {
                    resultMsg.setRet(syncResponse.getErrorCode());
                }

                if (resp.getReqProtocolType() != GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER) {
                    return;
                }

                if (resultMsg.getRet() == 0) {
                    resultMsg.setActivityId(GuaGiftsMgr.getConfig().getActivityId());
                    for (QixiProto.QixiRelationTemp temp : resp.getRelationListList()) {
                        resultMsg.setUserBaseInfo(temp.getUserBaseInfo());
                        resultMsg.setTargetUserId(targetUserId);
                        resultMsg.setMostGiftUserId(temp.getTargetUserId());
                        break;
                    }
                }

                sendGiftTargetMostUserInfo(fromServerId, fromUserId, resultMsg, giftType);

            });
        } else {
            GuaGiftsProto.GuaGiftsGetMostGiftTargetUserRespMsg.Builder resultMsg = GuaGiftsProto.GuaGiftsGetMostGiftTargetUserRespMsg.newBuilder();
            resultMsg.setRet(0);
            resultMsg.setActivityId(GuaGiftsMgr.getConfig().getActivityId());
            resultMsg.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            resultMsg.setTargetUserId(targetUserId);
            resultMsg.setMostGiftUserId(mostGiftUserId);
            sendGiftTargetMostUserInfo(fromServerId, fromUserId, resultMsg, giftType);
        }

    }

    public static void sendGiftTargetMostUserInfo(long fromServerId, long fromUserId, GuaGiftsProto.GuaGiftsGetMostGiftTargetUserRespMsg.Builder resultMsg, int giftType) {
        resultMsg.setGiftType(giftType);
        if (fromServerId == GameServer.getInstance().getServerId()) {
            GamePlayerMgr.sendPacket(fromUserId, YanQuMessageUtils.buildMessage(ClientProtocol.U_GUAGIFTS_GET_MOST_GIFT_TARGET_USER, resultMsg));
        } else {
            GamePlayerMgr.sendToGameServer(fromServerId, GameProtocol.S_GUAGIFTS_GET_MOST_GIFT_TARGET_USER_FROM_GAME, fromUserId, resultMsg, null);
        }
    }

    public static Property getGiftReward(GoodsInfo goodsInfo, int count) {
        ////物品类别161 花满七夕道具  参数列表：送花数|戒指id|戒指数量|每日赠送上限|是否广播,   赠送上限-1表示无限制，0表示不广播，1广播
        int rewardId = goodsInfo.getParamList().get(1).intValue();
        BigInteger rewardNum = goodsInfo.getParamList().get(2).multiply(BigInteger.valueOf(count));
        Property property = new Property();
        if (rewardId > 0) {//孤寡礼物会没有
            property = new Property(rewardId, rewardNum);
        }
        if (!goodsInfo.getExtendParam().equals("0")) {
            Property exReward = PropertyHelper.parseStringToProperty(goodsInfo.getExtendParam());
            exReward.goodCountMultiNum(count);
            property.addProperty(exReward);
        }

        return property;
    }

    public static GuaGiftsProto.GuaGiftsAllOpenServerListSyncMsg.Builder getAllOpenServerListMsg() {
        GuaGiftsProto.GuaGiftsAllOpenServerListSyncMsg.Builder builder = GuaGiftsProto.GuaGiftsAllOpenServerListSyncMsg.newBuilder();
        builder.addAllServerId(allServerList);
        return builder;
    }
}
